package org.ricks.net.protobuf;

import com.google.protobuf.Parser;
import io.netty.buffer.ByteBuf;
import org.ricks.ioc.utils.Logger;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author ricks [chenwei]
 * @Version [v1.0]
 * @CreateTime 2024-06-21   11:45
 * @Description TODO
 */
public class ProtoBufSeri {

    protected static final Map<Integer, Class<?>> protoEnumAndClass = new HashMap<>();

    private static final ThreadLocal<Map<Integer, Parser<?>>> protoEnumAndParser=new ThreadLocal<Map<Integer, Parser<?>>>(){

        @Override
        protected HashMap<Integer, Parser<?>> initialValue() {
            return new HashMap<>();
        }

    };

    public static Object unSeriImpl(int protoEnum, ByteBuf protoByteBuf, int protoBytesLen) {
        try{
            Parser<?> parser=protoEnumAndParser.get().get(protoEnum);
            if(parser!=null){
                return parser.parseFrom(protoByteBuf.array(), 0, protoBytesLen);
            }
            Class<?> clazz=protoEnumAndClass.get(protoEnum);
            Method method = clazz.getMethod("parser");
            Parser<?> reflectParser = (Parser<?>)method.invoke(null);
            protoEnumAndParser.get().put(protoEnum, reflectParser);
            return reflectParser.parseFrom(protoByteBuf.array(), 0, protoBytesLen);
        }catch(Exception e){
            Logger.error("ProtoBuf deserialize fail,protoEnum=[{}]" ,e,  protoEnum);
            Logger.error("", e);
            return null;
        }
    }

    public static Object unSeriImpl(int protoEnum, byte[] protoBytes, int off, int len) {
        try{
            Parser<?> parser=protoEnumAndParser.get().get(protoEnum);
            if(parser!=null){
                return parser.parseFrom(protoBytes, off, len);
            }
            Class<?> clazz=protoEnumAndClass.get(protoEnum);
            Method method = clazz.getMethod("parser");
            Parser<?> reflectParser = (Parser<?>)method.invoke(null);
            protoEnumAndParser.get().put(protoEnum, reflectParser);
            return reflectParser.parseFrom(protoBytes, off, len);
        }catch(Exception e){
            Logger.error("ProtoBuf deserialize fail,protoEnum=[{}]", e, protoEnum);
            Logger.error("", e);
            return null;
        }
    }
}
